﻿/**
 * jQuery EasyUI 1.3.6 Copyright (c) 2009-2014 www.jeasyui.com. All rights
 * reserved.
 * 
 * Licensed under the GPL or commercial licenses To use it on other terms please
 * contact author: info@jeasyui.com http://www.gnu.org/licenses/gpl.txt
 * http://www.jeasyui.com/license_commercial.php
 * 
 * jQuery EasyUI uploadify Plugin Extensions 1.0 beta jQuery EasyUI uploadify
 * 插件扩展 jquery.euploadify.js 二次开发 流云 最近更新：2014-05-23
 * 
 * 依赖项： 1、jquery.jdirk.js v1.0 beta late 2、jeasyui.extensions.js v1.0 beta late
 * 3、jeasyui.extensions.menu.js v1.0 beta late 4、jeasyui.extensions.panel.js
 * v1.0 beta late 和 jeasyui.extensions.window.js v1.0 beta late(可选)
 * 5、jeasyui.extensions.progressbar.js v1.0 beta late
 * 
 * 6、uploadify/jquery.uploadify.js 7、uploadify/uploadify.css
 * 8、uploadify/uploadify.swf
 * 9、uploadify/uploadify.php|uploadify.ashx|uploadify.jsp
 * 
 * Copyright (c) 2013-2014 ChenJianwei personal All rights reserved.
 * http://www.chenjianwei.org
 */
(function($, undefined) {

	function create(target) {
		var t = $(target).addClass("euploadify-f").hide(), state = $.data(target, "euploadify"), opts = state.options, name = state.name = t
				.attr("name");

		state.uploadifyID = "euploadify_" + $.util.guid("N");
		state.queueID = "euploadify_queue_" + $.util.guid("N");
		state.lastFileID = null;

		state.panel = $("<div class=\"euploadify-panel\"></div>").insertAfter(t).append(t).panel($.extend({}, opts, {
			onResize : function(width, height) {
				$.fn.panel.defaults.onResize.apply(this, arguments);
				$.extend(opts, {
					width : width,
					height : height
				});
				setSize(target);
				if ($.isFunction(opts.onResize)) {
					opts.onResize.apply(target, arguments);
				}
			}
		}));
		state.wrapper = state.panel.panel("body").addClass("euploadify-wrapper");
		state.queueDOM = $("<div id=\"" + state.queueID + "\" class=\"euploadify-queue\"></div>").appendTo(state.wrapper);
		state.queues = [];

		t.removeAttr(name).attr("euploadifyName", name);

		opts.originalValue = opts.value;
		opts.originalFormData = $.extend({}, opts.formData);

		initializeUploadify(target);
		setValues(target, opts.value);
		setSize(target);
		if (opts.disabled) {
			disable(target, opts.disabled);
		}
		setValidation(target)
	}
	;

	function refreshQueueStatus(queues, file, value) {
		var q = $.array.first(queues, function(f) {
			return f.id == file.id;
		})
		if (q) {
			q.filestatus = file.filestatus;
			if (value != null) {
				q.value = value;
			}
		}
	}
	;

	function initializeUploadify(target) {
		var t = $(target), state = $.data(target, "euploadify"), opts = state.options, template = String(opts.multiTemplate).toLowerCase();
		if (!$.array.contains([ "uploadify", "simple", "bootstrap", "grid" ], template)) {
			template = $.fn.euploadify.defaults.multiTemplate;
		}
		var uopts = {
			auto : opts.auto,
			method : opts.method,
			multi : opts.multi,
			buttonClass : opts.buttonClass,
			buttonCursor : opts.buttonCursor,
			buttonImage : opts.buttonImage,
			buttonText : opts.buttonText,
			checkExisting : opts.checkExisting,
			debug : opts.debug,
			fileObjName : opts.fileObjName,
			fileSizeLimit : opts.fileSizeLimit,
			fileTypeDesc : opts.fileTypeDesc,
			fileTypeExts : opts.fileTypeExts,
			formData : opts.formData,
			progressData : opts.progressData,
			width : opts.buttonWidth,
			height : opts.buttonHeight,
			queueID : state.queueID,
			itemTemplate : opts.multi && template != "custome" ? opts.multiTemplateData[template] : opts.itemTemplate,
			overrideEvents : opts.overrideEvents,
			preventCaching : opts.preventCaching,
			queueSizeLimit : opts.queueSizeLimit,
			uploadLimit : opts.uploadLimit,
			removeCompleted : opts.removeCompleted,
			removeTimeout : opts.removeTimeout,
			requeueErrors : opts.requeueErrors,
			swf : opts.swf,
			uploader : opts.uploader,
			successTimeout : opts.successTimeout,

			onCancel : function(file) {
				$.array.remove(state.queues, file, function(q) {
					return file.id == q.id;
				});
				return opts.onCancel.apply(target, arguments);
			},
			onClearQueue : function() {
				state.queues = [];
				return opts.onClearQueue.apply(target, arguments);
			},
			onDestroy : function() {
				state.queues = null;
				return opts.onDestroy.apply(target, arguments);
			},
			onDialogClose : function() {
				return opts.onDialogClose.apply(target, arguments);
			},
			onDialogOpen : function() {
				return opts.onDialogOpen.apply(target, arguments);
			},
			onDisable : function() {
				return opts.onDisable.apply(target, arguments);
			},
			onEnable : function() {
				return opts.onEnable.apply(target, arguments);
			},
			onFallback : function() {
				return opts.onFallback.apply(target, arguments);
			},
			onInit : function() {
				return opts.onInit.apply(target, arguments);
			},
			onQueueComplete : function() {
				return opts.onQueueComplete.apply(target, arguments);
			},
			onSelect : function(file) {
				state.queues.push($.extend({}, file));
				return opts.onSelect.apply(target, arguments);
			},
			onSelectError : function() {
				return opts.onSelectError.apply(target, arguments);
			},
			onSWFReady : function() {
				return opts.onSWFReady.apply(target, arguments);
			},
			onUploadComplete : function(file) {
				refreshQueueStatus(state.queues, file);
				return opts.onUploadComplete.apply(target, arguments);
			},
			onUploadError : function(file, errorCode, errorMsg, errorString) {
				refreshQueueStatus(state.queues, file);
				return opts.onUploadError.apply(target, arguments);
			},
			onUploadProgress : function(file, bytesUploaded, bytesTotal, totalBytesUploaded, totalBytesTotal) {
				// refreshQueueStatus(state.queues, file);
				return opts.onUploadProgress.apply(target, arguments);
			},
			onUploadStart : function(file) {
				refreshQueueStatus(state.queues, file);
				return opts.onUploadStart.apply(target, arguments);
			},
			onUploadSuccess : function(file, data, response) {
				var obj = opts.responseFilter.call(target, data, file), val = file.value = obj && obj.value != null
						&& obj.value != undefined ? obj.value : null;
				refreshQueueStatus(state.queues, file, val);

				var values = opts.multi ? $.array.map(getQueuesByStatus(target, -4), function(f) {
					return f.value;
				}) : [ val ];
				setValues(target, values);
				return opts.onUploadSuccess.apply(target, arguments);
			}
		};
		if (opts.multi) {
			state.wrapper.addClass("euploadify-wrapper-multi euploadify-wrapper-multi-" + template);
			state.buttonbar = $("<div class=\"euploadify-buttonbar\"></div>").insertBefore(state.queueDOM);
			if (template == "grid") {
				buildGridPanel(target, uopts);
			} else {
				buildMultiPanel(target, uopts);
			}
		} else {
			state.wrapper.addClass("euploadify-wrapper-single");
			state.queueDOM.addClass("euploadify-hidden");
			state.progressbar = $("<div class=\"euploadify-progressbar\"></div>").insertBefore(state.queueDOM).progressbar({
				width : 400,
				height : 18,
				value : 0,
				text : opts.emptyText
			});
			state.buttonbar = $("<div class=\"euploadify-buttonbar\"></div>").insertAfter(state.progressbar);

			var onCancel = uopts.onCancel, onSelect = uopts.onSelect, onUploadStart = uopts.onUploadStart, onUploadProgress = uopts.onUploadProgress, onUploadError = uopts.onUploadError, onUploadSuccess = uopts.onUploadSuccess;
			$.extend(uopts, {
				onCancel : function(file) {
					var ret = onCancel.apply(this, arguments), queues = getQueues(target);
					if (!queues.length) {
						state.progressbar.progressbar("setText", opts.emptyText).progressbar("setValue", 0);
						return ret;
					}
					if (queues.length) {
						state.progressbar.progressbar("setText",
								getFileName(target, queues[0]) + "(" + $.number.toFileSize(file.size) + ") - 0%")
								.progressbar("setValue", 0);
					} else {
						state.progressbar.progressbar("setText", opts.emptyText).progressbar("setValue", 0);
					}
					return ret;
				},
				onSelect : function(file) {
					var ret = onSelect.apply(this, arguments);
					if (state.lastFileID && !opts.multi) {
						state.uploadify.uploadify("cancel", state.lastFileID);
					}
					if (file) {
						state.progressbar.progressbar("setText",
								getFileName(target, file) + "(" + $.number.toFileSize(file.size) + ") - 0%").progressbar("setValue", 0)
								.find(".progressbar-value .progressbar-text")
								.removeClass("progressbar-text-success progressbar-text-error");
						state.lastFileID = file.id;
					} else {
						state.progressbar.progressbar("setText", opts.emptyText).progressbar("setValue", 0).find(
								".progressbar-value .progressbar-text").removeClass("progressbar-text-success progressbar-text-error");
					}
					return ret;
				},
				onUploadStart : function(file) {
					var ret = onUploadStart.apply(this, arguments);
					t.euploadify("resetFormData");
					var data = $.extend({}, file, {
						customeName : file.name
					}), formData = opts.requestFilter.call(target, data, file);
					state.uploadify.uploadify("settings", "formData", formData);
					return ret;
				},
				onUploadProgress : function(file, bytesUploaded, bytesTotal, totalBytesUploaded, totalBytesTotal) {
					var ret = onUploadProgress.apply(this, arguments), val = !bytesTotal ? 0 : (bytesUploaded / bytesTotal * 100).round(2);
					state.progressbar.progressbar("setText",
							getFileName(target, file) + "(" + $.number.toFileSize(file.size) + ") - {value}%").progressbar("setValue", val)
							.find(".progressbar-value .progressbar-text").removeClass("progressbar-text-success progressbar-text-error");
					return ret;
				},
				onUploadError : function(file, errorCode, errorMsg, errorString) {
					var ret = onUploadError.apply(this, arguments);
					if (!$.array.contains([ "Cancelled", "Stopped" ], errorString)) {
						state.progressbar
								.progressbar("setText", getFileName(target, file) + "(" + opts.errorText + ":" + errorString + ")").find(
										".progressbar-value .progressbar-text").removeClass(
										"progressbar-text-success progressbar-text-error").addClass("progressbar-text-error");
					}
					return ret;
				},
				onUploadSuccess : function(file, data, response) {
					var ret = onUploadSuccess.apply(this, arguments);
					state.progressbar.progressbar("setText", getFileName(target, file) + "(" + opts.finishText + ")").progressbar(
							"setValue", 100).find(".progressbar-value .progressbar-text").removeClass(
							"progressbar-text-success progressbar-text-error").addClass("progressbar-text-success");
					return ret;
				}
			});
		}

		state.button = $(
				"<a class=\"l-btn l-btn-small euploadify-button euploadify-select" + (opts.buttonPlain ? " l-btn-plain" : "")
						+ "\"><span class=\"l-btn-left l-btn-icon-left\"><span class=\"l-btn-icon " + opts.buttonIcon
						+ "\">&nbsp;</span></span></a>").appendTo(state.buttonbar);
		state.uploadify = $("<input id=\"" + state.uploadifyID + "\" type=\"file\" />").insertBefore(state.button.find("span.l-btn-icon"))
				.uploadify(uopts);
		state.uploadify = $("#" + state.uploadifyID);

		state.uploadButton = $(
				"<a class=\"euploadify-button euploadify-upload" + (opts.auto && !opts.multi ? " euploadify-hidden" : "") + "\"></a>")
				.appendTo(state.buttonbar).linkbutton({
					plain : opts.buttonPlain,
					text : opts.uploadText,
					iconCls : opts.uploadIcon,
					onClick : function() {
						var queues = getQueues(target), ff = $.array.first(queues, function(val) {
							return val.filestatus != -4;
						});
						if (!queues || !queues.length || !ff) {
							return $.easyui.messager.show(opts.message.queueEmpty);
						}
						state.uploadify.uploadify("upload", "*");
					}
				});

		state.stopButton = $("<a class=\"euploadify-button euploadify-stop" + (!opts.showStop ? " euploadify-hidden" : "") + "\"></a>")
				.appendTo(state.buttonbar).linkbutton({
					plain : opts.buttonPlain,
					text : opts.stopText,
					iconCls : opts.stopIcon,
					onClick : function() {
						state.uploadify.uploadify("stop");
						return opts.onButtonStop.call(target, getQueues(target), this);
					}
				});

		state.cancelButton = $(
				"<a class=\"euploadify-button euploadify-cancel" + (!opts.showCancel ? " euploadify-hidden" : "") + "\"></a>").appendTo(
				state.buttonbar).linkbutton({
			plain : opts.buttonPlain,
			text : opts.cancelText,
			iconCls : opts.cancelIcon,
			onClick : function() {
				state.uploadify.uploadify("cancel", "*");
			}
		});

		if (opts.multi && template == "grid") {
			$("<span>-</span>").insertAfter(state.button);
			if (!opts.auto) {
				$("<span>-</span>").insertAfter(state.uploadButton);
			}
			if (opts.showStop || opts.showCancel) {
				$("<span>-</span>").appendTo(state.buttonbar);
			}

			state.removeButton = $("<a class=\"euploadify-button\"></a>").appendTo(state.buttonbar).linkbutton({
				plain : opts.buttonPlain,
				text : opts.removeText,
				iconCls : "icon-hamburg-busy",
				onClick : function() {
					var rows = state.grid.datagrid("getChecked"), array = $.array.clone(rows);
					if (!rows || !rows.length) {
						return $.easyui.messager.show(opts.message.mustNotEmpty);
					}
					$.each(array, function(i, row) {
						var index = state.grid.datagrid("getRowIndex", row);
						if (index > -1) {
							state.grid.datagrid("deleteRow", index);
						}
						state.uploadify.uploadify("cancel", row.id);
						$.array.remove(state.queues, row, function(q) {
							return row.id == q.id;
						});
					});
					var values = $.array.map(getQueuesByStatus(target, -4), function(f) {
						return f.value;
					});
					setValues(target, values);
				}
			});

			state.buttonbar.toolbar();
		}

		if (opts.tooltip) {
			var tooltip = opts.tooltip === true ? $.fn.euploadify.defaults.tooltip : opts.tooltip;
			if (state.button) {
				state.button.tooltip({
					content : tooltip.button
				});
			}
			if (state.uploadButton) {
				state.uploadButton.tooltip({
					content : tooltip.upload
				});
			}
			if (state.stopButton) {
				state.stopButton.tooltip({
					content : tooltip.stop
				});
			}
			if (state.cancelButton) {
				state.cancelButton.tooltip({
					content : tooltip.cancel
				});
			}
			if (state.removeButton) {
				state.removeButton.tooltip({
					content : tooltip.remove
				});
			}
		}
	}
	;

	function buildMultiPanel(target, uopts) {
		var t = $(target), state = $.data(target, "euploadify"), opts = state.options, onUploadStart = uopts.onUploadStart;
		state.queueDOM.on("click", ".uploadify-queue-item .cancel a", function() {
			var item = $(this).closest(".uploadify-queue-item"), id = item.attr("id");
			$.array.remove(state.queues, id, function(q) {
				return q.id == id;
			});
			var queues = getQueuesByStatus(target, -4), values = $.array.map(queues, function(q) {
				return q.value;
			});
			setValues(target, values.length ? values : [ null ])
		});
		$.extend(uopts, {
			onUploadStart : function(file) {
				var ret = onUploadStart.apply(this, arguments);
				// t.euploadify("resetFormData");
				var data = $.extend({}, file, {
					customeName : file.name
				}), formData = opts.requestFilter.call(target, data, file);
				state.uploadify.uploadify("settings", "formData", formData);
				return ret;
			}
		});
	}
	;

	function buildGridPanel(target, uopts) {
		var t = $(target), state = $.data(target, "euploadify"), opts = state.options, layout = state.layout = $(
				"<div class=\"euploadify-gridpanel-layout\"></div>").insertBefore(state.queueDOM), north = state.north = $(
				"<div class=\"euploadify-gridpanel-north\" data-options=\"region: 'north', split: false, border: false\" style=\"height: 33px;\"></div>")
				.appendTo(layout).append(state.buttonbar), center = state.center = $(
				"<div class=\"euploadify-gridpanel-center\" data-options=\"region: 'center', border: false\"></div>").appendTo(layout), grid = state.grid = $(
				"<table class=\"euploadify-gridpanel-grid\"></table>").appendTo(center);
		state.queueDOM.addClass("euploadify-hidden");
		layout.layout({
			fit : true
		});
		grid
				.datagrid({
					fit : true,
					border : false,
					idField : "id",
					rownumbers : true,
					refreshMenu : false,
					extEditing : true,
					singleEditing : true,
					frozenColumns : [ [ {
						field : "ck",
						checkbox : true,
						filterable : false
					}, {
						field : "name",
						title : "全文件名",
						width : 100,
						filterable : false
					} ] ],
					columns : [ [
							{
								field : "customeName",
								title : opts.gridColumnNames.customeName,
								width : 120,
								editor : "text",
								filterable : false
							},
							{
								field : "type",
								title : opts.gridColumnNames.type,
								width : 60,
								filterable : false
							},
							{
								field : "size",
								title : opts.gridColumnNames.size,
								width : 80,
								filterable : false,
								formatter : function(val) {
									return $.number.toFileSize(val);
								}
							},
							{
								field : "progress",
								title : opts.gridColumnNames.progress,
								width : 80,
								align : "center",
								filterable : false,
								formatter : function(val, row) {
									return "<div class=\"euploadify-gridpanel-progress\">"
											+ "<div class=\"euploadify-gridpanel-progress-value"
											+ (row.filestatus == -3 ? " euploadify-gridpanel-progress-error"
													: (row.filestatus == -4 ? " euploadify-gridpanel-progress-success" : ""))
											+ "\" style=\"width: " + String(val || 0) + "%;\"></div>" + "</div>";
								}
							},
							{
								field : "progressValue",
								title : opts.gridColumnNames.progressValue,
								width : 50,
								filterable : false,
								formatter : function(val) {
									return String(val || 0) + "%";
								}
							},
							{
								field : "filestatus",
								title : opts.gridColumnNames.filestatus,
								width : 80,
								filterable : false,
								formatter : function(val, row, index) {
									var str = opts.FILE_STATUS[val], ret = val == -3 ? ("<span title=\"" + row.errorString
											+ "\" class=\"euploadify-gridpanel-status euploadify-gridpanel-status-error\">" + str + "</span>")
											: (val == -4 ? ("<span class=\"euploadify-gridpanel-status euploadify-gridpanel-status-success\">"
													+ str + "</span>")
													: str);
									return ret;
								}
							},
							{
								field : "operate",
								title : opts.gridColumnNames.operate,
								width : 80,
								filterable : false,
								formatter : function(val, row) {
									return "<div title=\""
											+ opts.gridRowButtonNames.cancel
											+ "\" class=\"euploadify-button-mini\" onclick=\"javascript: return $.fn.euploadify.cancelQueue(this);\">\
                                    <span class=\"euploadify-button-mini-icon icon-standard-delete\">&nbsp;</span>\
                                </div>\
                                <div title=\""
											+ opts.gridRowButtonNames.upload
											+ "\" class=\"euploadify-button-mini\" onclick=\"javascript: return $.fn.euploadify.uploadQueue(this);\">\
                                    <span class=\"euploadify-button-mini-icon icon-standard-arrow-up\">&nbsp;</span>\
                                </div>";
								}
							} ] ],
					rowContextMenu : [ {
						text : opts.gridRowContextNames.edit,
						iconCls : "icon-edit",
						disabled : function() {
							return opts.disabled || state.wrapper.is(".euploadify-disabled");
						},
						handler : function(e, index, row) {
							grid.datagrid("beginEdit", index);
						}
					}, {
						text : opts.gridRowContextNames.cancel,
						iconCls : "icon-standard-delete",
						disabled : function() {
							return opts.disabled || state.wrapper.is(".euploadify-disabled");
						},
						handler : function(e, index, row) {
							if (row.filestatus == -4) {
								$.easyui.messager.show(opts.message.fileUploadSuccessCanntCancel);
							} else {
								state.uploadify.uploadify("cancel", row.id);
							}
						}
					}, {
						text : opts.gridRowContextNames.upload,
						iconCls : "icon-standard-arrow-up",
						disabled : function() {
							return opts.disabled || state.wrapper.is(".euploadify-disabled");
						},
						handler : function(e, index, row) {
							if (row.filestatus == -4) {
								$.easyui.messager.show(opts.message.fileUploadSuccess);
							} else {
								state.uploadify.uploadify("upload", row.id);
							}
						}
					} ],
					onBeginEdit : function(index, row) {
						if ($.array.contains([ -2, -4, -5 ], row.filestatus)) {
							var msg = $.string.format(opts.message.fileCannotRename, opts.FILE_STATUS[row.filestatus]);
							$.easyui.messager.show(msg);
							grid.datagrid("cancelEdit", index);
						}
						return $.fn.datagrid.defaults.onBeginEdit.apply(this, arguments);
					},
					onAfterEdit : function(index, row, changes) {
						if (!row.customeName) {
							$.easyui.messager.show(opts.message.fileNameCannotEmpty);
							var array = String(row.name).split("."), temp = $.array.removeAt(array, array.length - 1), name = temp.join("");
							grid.datagrid("updateRow", {
								index : index,
								row : {
									customeName : name
								}
							});
						}
						return $.fn.datagrid.defaults.onAfterEdit.apply(this, arguments);
					}
				});

		var onCancel = uopts.onCancel, onSelect = uopts.onSelect, onUploadStart = uopts.onUploadStart, onUploadProgress = uopts.onUploadProgress, onUploadError = uopts.onUploadError, onUploadComplete = uopts.onUploadComplete;
		$
				.extend(
						uopts,
						{
							onCancel : function(file) {
								var ret = onCancel.apply(this, arguments), id = file.id, index = grid.datagrid("getRowIndex", id);
								if (index > -1) {
									grid.datagrid("deleteRow", index);
								}
								return ret;
							},
							onSelect : function(file) {
								var ret = onSelect.apply(this, arguments), nameArray = String(file.name).split("."), tempName = $.array
										.removeAt(nameArray, nameArray.length - 1), name = tempName.join(""), row = $.extend({}, file, {
									customeName : name,
									progress : 0,
									progressValue : 0
								});
								grid.datagrid("appendRow", row);
								return ret;
							},
							onUploadStart : function(file) {
								var ret = onUploadStart.apply(this, arguments), id = file.id, index = grid.datagrid("getRowIndex", id), row = index > -1 ? grid
										.datagrid("getRowData", index)
										: null;
								if (row) {
									t.euploadify("resetFormData");
									var data = $.extend({}, row, {
										customeName : row.customeName + file.type
									}), formData = opts.requestFilter.call(target, data, file);
									state.uploadify.uploadify("settings", "formData", formData);
									grid.datagrid("updateRow", {
										index : index,
										row : {
											filestatus : file.filestatus
										}
									});
								}
								return ret;
							},
							onUploadProgress : function(file, bytesUploaded, bytesTotal, totalBytesUploaded, totalBytesTotal) {
								var ret = onUploadProgress.apply(this, arguments), val = !bytesTotal ? 0
										: (bytesUploaded / bytesTotal * 100).round(2), id = file.id, index = grid.datagrid("getRowIndex",
										id);
								if (index > -1) {
									grid.datagrid("updateRow", {
										index : index,
										row : {
											progress : val,
											progressValue : val,
											filestatus : file.filestatus
										}
									});
								}
								return ret;
							},
							onUploadError : function(file, errorCode, errorMsg, errorString) {
								var ret = onUploadError.apply(this, arguments), id = file.id, index = grid.datagrid("getRowIndex", id), row = index > -1 ? grid
										.datagrid("getRowData", index)
										: null;
								if (row) {
									state.uploadify.uploadify("settings", "formData", row);
									grid.datagrid("updateRow", {
										index : index,
										row : {
											errorString : errorCode + "," + errorMsg + "," + errorString
										}
									});
								}
								return onUploadError.apply(this, arguments);
							},
							onUploadComplete : function(file) {
								var ret = onUploadComplete.apply(this, arguments), id = file.id, index = grid.datagrid("getRowIndex", id);
								if (index > -1) {
									grid.datagrid("updateRow", {
										index : index,
										row : {
											filestatus : file.filestatus
										}
									});
								}
								return ret;
							}
						});
	}
	;

	function getOptions(target) {
		var state = $.data(target, "euploadify"), opts = state.panel.panel("options");
		return $.extend(state.options, {
			title : opts.title,
			iconCls : opts.iconCls,
			width : opts.width,
			height : opts.height,
			left : opts.left,
			top : opts.top,
			cls : opts.cls,
			headerCls : opts.headerCls,
			bodyCls : opts.bodyCls,
			style : opts.style,
			fit : opts.fit,
			border : opts.border,
			doSize : opts.doSize,
			noheader : opts.noheader,
			collapsible : opts.collapsible,
			minimizable : opts.minimizable,
			maximizable : opts.maximizable,
			closable : opts.closable,
			collapsed : opts.collapsed,
			minimized : opts.minimized,
			maximized : opts.maximized,
			closed : opts.closed
		});
	}
	;

	function getUploadify(target) {
		return $.data(target, "euploadify").uploadify;
	}
	;

	function getButtons(target) {
		return $.data(target, "euploadify").buttonbar.find("a.euploadify-button");
	}
	;

	function getFileName(target, file) {
		if (!file || !file.name) {
			return $(target).euploadify("options").emptyText;
		}
		return $.string.getByteLen(file.name) > 28 ? $.string.leftBytes(file.name, 25) + "..." : file.name;
	}
	;

	function getQueueDOM(target) {
		return $.data(target, "euploadify").queueDOM;
	}
	;

	function getGrid(target) {
		return $.data(target, "euploadify").grid;
	}
	;

	function getQueues(target) {
		return $.array.clone($.data(target, "euploadify").queues);
	}
	;

	function getQueuesByStatus(target, status) {
		return $.array.filter(getQueues(target), function(q) {
			return q.filestatus == status;
		});
	}
	;

	function setSize(target) {
		var t = $(target), state = $.data(target, "euploadify"), opts = state.options;
		if (state.buttonbar && state.progressbar && !opts.multi) {
			var fit = t._fit(false), width = fit.width - state.buttonbar.outerWidth() - 15;
			state.progressbar.progressbar("resize", width);
		}
	}
	;

	function cancel(target, param) {
		var state = $.data(target, "euploadify");
		state.uploadify.uploadify("cancel", param);
	}
	;

	function setQueueData(target, file) {
		var state = $.data(target, "euploadify");
		state.uploadify.uploadify("setQueueData", file);
		state.queues.push($.extend({}, file));
	}

	function destroy(target) {
		var t = $(target), state = $.data(target, "euploadify");
		state.uploadify.uploadify("destroy");
		state.panel.panel("destroy");
		t.remove();
	}
	;

	function disable(target, setDisabled) {
		if (setDisabled == null || setDisabled == undefined) {
			setDisabled = true;
		}
		var t = $(target), state = $.data(target, "euploadify"), opts = state.options;
		opts.disabled = setDisabled;
		var buttons = state.buttonbar.find(".euploadify-button:not(.euploadify-select)");
		if (setDisabled) {
			t.attr("disabled", true);
			state.wrapper.addClass("euploadify-disabled");
			state.button.addClass("l-btn-disabled");
			if (opts.buttonPlain) {
				state.button.addClass("l-btn-plain-disabled");
			}
			$.util.tryExec(function() {
				state.uploadify.uploadify("stop");
			});
			buttons.linkbutton("disable");
		} else {
			t.removeAttr("disabled");
			state.wrapper.removeClass("euploadify-disabled");
			state.button.removeClass("l-btn-disabled");
			if (opts.buttonPlain) {
				state.button.removeClass("l-btn-plain-disabled");
			}
			buttons.linkbutton("enable");
		}
		$.util.tryExec(function() {
			state.uploadify.uploadify("disable", setDisabled);
		});
	}
	;

	function enable(target) {
		disable(target, false);
	}
	;

	function stop(target) {
		$.data(target, "euploadify").uploadify.uploadify("stop");
	}
	;

	function upload(target, param) {
		$.data(target, "euploadify").uploadify.uploadify("upload", param);
	}
	;

	function resize(target, param) {
		var state = $.data(target, "euploadify");
		state.panel.panel("resize", param);
	}
	;

	function settings(target, param) {
		var t = $(target);
		if (!param) {
			return t;
		}
		var state = $.data(target, "euploadify"), opts = state.options;
		if (typeof param == "string") {
			return opts[param];
		} else {
			if (param.name) {
				opts[param.name] = param.value;
				state.uploadify.uploadify("settings", param.name, param.value);
			}
			return t;
		}
	}
	;

	function setFormData(target, param) {
		param = param || {};
		var state = $.data(target, "euploadify"), opts = state.options, swfuploadify = state.uploadify.data("uploadify"), settings = swfuploadify.settings;
		settings.formData = {};
		swfuploadify.setPostParams(opts.formData = $.extend(settings.formData, param));
	}
	;

	function resetFormData(target) {
		var state = $.data(target, "euploadify"), opts = state.options;
		setFormData(target, opts.originalFormData);
	}
	;

	function clearFormData(target) {
		setFormData(target, {});
	}
	;

	function hideTip(target) {
		var state = $.data(target, "euploadify");
		state.tip = false;
		state.wrapper.tooltip("hide");
	}
	;

	function showTip(target) {
		var state = $.data(target, "euploadify"), opts = state.options;
		state.wrapper.tooltip($.extend({}, opts.tipOptions, {
			content : opts.missingMessage,
			position : opts.tipPosition,
			deltaX : opts.deltaX
		})).tooltip("show");
		state.tip = true;
	}
	;

	function repositionTip(target) {
		var state = $.data(target, "euploadify");
		if (state && state.tip) {
			state.wrapper.tooltip("reposition");
		}
	}
	;

	function initializeValidate(target) {
		var t = $(target), state = $.data(target, "euploadify"), opts = state.options;
		state.wrapper.unbind(".euploadify");
		if (opts.novalidate) {
			return;
		}
		state.wrapper.bind("focus.euploadify", function() {
			state.validating = true;
			state.values = undefined;
			(function() {
				if (state.validating) {
					var values = t.euploadify("getValues").join(opts.separator);
					if (state.values != values) {
						state.values = values;
						if (state.timer) {
							clearTimeout(state.timer);
						}
						state.timer = setTimeout(function() {
							t.euploadify("validate");
						}, opts.delay);
					} else {
						repositionTip(target);
					}
					setTimeout(arguments.callee, 200);
				}
			})();
		}).bind("blur.euploadify", function() {
			if (state.timer) {
				clearTimeout(state.timer);
				state.timer = undefined;
			}
			state.validating = false;
			hideTip(target);
		}).bind("mouseenter.euploadify", function() {
			if (state.wrapper.hasClass("euploadify-invalid")) {
				showTip(target);
			}
		}).bind("mouseleave.euploadify", function() {
			if (!state.validating) {
				hideTip(target);
			}
		});
	}
	;

	function validate(target) {
		var t = $(target), state = $.data(target, "euploadify"), opts = state.options, values = t.euploadify("getValues"), str = values
				.join(opts.separator);
		state.wrapper.removeClass("euploadify-invalid");
		hideTip(target);
		if (!opts.novalidate && opts.required && (!values.length || !str) && !t.is(":disabled")
				&& !state.wrapper.hasClass("euploadify-disabled")) {
			state.wrapper.addClass("euploadify-invalid");
			if (state.validating) {
				showTip(target);
			}
			return false;
		}
		return true;
	}
	;

	function setValidation(target, novalidate) {
		var state = $.data(target, "euploadify"), opts = state.options;
		if (novalidate != undefined && novalidate != null) {
			opts.novalidate = novalidate;
		}
		if (opts.novalidate) {
			state.wrapper.removeClass("euploadify-invalid");
			hideTip(target);
		}
		initializeValidate(target);
	}
	;

	function getValues(target) {
		var state = $.data(target, "euploadify"), opts = state.options, fields = state.wrapper.find(".euploadify-value"), values = $.array
				.map(fields, function(val) {
					return $(val).val();
				});
		state.values = values.join(opts.separator);
		return opts.values = values;
	}
	;

	function getValue(target) {
		var values = getValues(target);
		return values[0];
	}
	;

	function setValues(target, values) {
		var t = $(target), state = $.data(target, "euploadify"), opts = state.options, original = t.euploadify("getValues"), array = $.util
				.likeArrayNotString(values) ? values : [ values ];
		state.wrapper.find(".euploadify-value").remove();
		$.each(array, function(i, val) {
			var field = $("<input class=\"euploadify-value\" type=\"hidden\" />").appendTo(state.wrapper).val(val);
			if (state.name) {
				field.attr("name", state.name);
			}
		});
		var temps = $.array.filter(array, function(val) {
			return $.array.contains(original, val) ? false : true;
		});
		if (temps.length != array.length || array.length != original.length) {
			if (opts.multi) {
				opts.onChange.call(target, array, original);
			} else {
				opts.onChange.call(target, array[0], original[0]);
			}
		}
		state.values = array.join(opts.separator);
		opts.values = array;
	}
	;

	function setValue(target, value) {
		setValues(target, [ value ]);
	}
	;

	function clear(target) {
		setValues(target, []);
	}
	;

	function reset(target) {
		var state = $.data(target, "euploadify"), opts = state.options;
		setValues(target, opts.originalValue);
	}
	;

	function show(target) {
		var state = $.data(target, "euploadify");
		state.panel.panel("open");
		return getOptions(target);
	}
	;

	function hide(target) {
		var state = $.data(target, "euploadify");
		state.panel.panel("close");
		return getOptions(target);
	}
	;

	$.fn.euploadify = function(options, param) {
		if (typeof options == "string") {
			var method = $.fn.euploadify.methods[options];
			if (method) {
				return method(this, param);
			} else {
				return this.euploadify("panel").panel(options, param);
			}
		}
		options = options || {};
		return this.each(function() {
			var state = $.data(this, "euploadify");
			if (state) {
				$.extend(state.options, options);
			} else {
				$.data(this, "euploadify", {
					options : $.extend({}, $.fn.euploadify.defaults, $.fn.euploadify.parseOptions(this), options)
				});
				create(this);
			}
		});
	};

	function operateQueue(mini, method) {
		var btn = $(mini), t = btn.closest("div.euploadify-wrapper").find(".euploadify-f"), state = $.data(t[0], "euploadify"), opts = state.options;
		if (!opts.disabled && !state.wrapper.is(".euploadify-disabled")) {
			var index = window.parseInt(btn.closest("tr.datagrid-row").attr("datagrid-row-index")), row = state.grid.datagrid("getRowData",
					index);
			if (row.filestatus == -4) {
				var msg = {
					cancel : opts.message.fileUploadSuccessCanntRemove,
					upload : opts.message.fileUploadSuccess
				};
				$.easyui.messager.show(msg[method]);
			} else {
				state.uploadify.uploadify(method, row.id);
			}
		}
		if (window.event && window.event.stopPropagation) {
			window.event.stopPropagation();
		}
		return false;
	}
	;

	$.fn.euploadify.cancelQueue = function(mini) {
		return operateQueue(mini, "cancel");
	};

	$.fn.euploadify.uploadQueue = function(mini) {
		return operateQueue(mini, "upload");
	};

	$.fn.euploadify.parseOptions = function(target) {
		return $.extend({}, $.parser.parseOptions(target, [ "buttonClass", "buttonCursor", "buttonImage", "buttonText", "checkExisting",
				"fileObjName", "fileTypeDesc", "fileTypeExts", "itemTemplate", "method", "progressData", "queueID", "swf", "uploader",
				"uploadText", "stopText", "cancelText", "removeText", "emptyText", "finishText", "errorText", "buttonIcon", "stopIcon",
				"cancelIcon", "uploadIcon", "multiTemplate", "value", "width", "height", "missingMessage", "tipPosition", "separator", {
					auto : "boolean",
					debug : "boolean",
					multi : "boolean",
					preventCaching : "boolean",
					removeCompleted : "boolean",
					requeueErrors : "boolean",
					disabled : "boolean",
					buttonPlain : "boolean",
					showStop : "boolean",
					showCancel : "boolean",
					required : "boolean",
					novalidate : "boolean"
				}, {
					fileSizeLimit : "number",
					height : "number",
					queueSizeLimit : "number",
					removeTimeout : "number",
					successTimeout : "number",
					uploadLimit : "number",
					width : "number",
					buttonWidth : "number",
					buttonHeight : "number",
					deltaX : "number"
				} ]));
	};

	// 提供外部调用公共方法 $.easyui.showEuploadifyDialog 用于快速创建 euploadify 文件上传对话框；
	// 该方法的参数 options 参考继承于方法 $.easyui.showDialog 和插件 easyui-euploadify
	// 的参数格式，在在此基础上增加了如下描述的属性：
	// title : string
	// value : string
	// onEnter : function(val, euploadify, uploadify, btn)
	// onCancel: function(val, euploadify, uploadify, btn)
	// ...
	// 返回值：返回创建的 easyui-dialog 对象；
	$.easyui.showEuploadifyDialog = function(options) {
		if (options && options.topMost && $ != $.util.$ && $.util.$.easyui.showEuploadifyDialog) {
			return $.util.$.easyui.showEuploadifyDialog.apply(this, options);
		}
		var opts = $.extend({}, $.easyui.showEuploadifyDialog.defaults, options || {}), euploadify, uploadify, value = opts.value, dia = $.easyui
				.showDialog($.extend({}, opts, {
					content : "<input class=\"euploadify-dialog-container\" />",
					enableApplyButton : false,
					topMost : false,
					height : opts.height == "auto" ? (opts.multi ? 480 : 160) : opts.height,
					onBeforeDestroy : function() {
						if (euploadify) {
							euploadify.euploadify("destroy");
						}
					},
					onSave : function() {
						return opts.onEnter.call(dia, getValue(), euploadify, uploadify, this);
					},
					onClose : function() {
						return opts.onCancel.call(dia, getValue(), euploadify, uploadify, this);
					}
				}));
		$.util.exec(function() {
			var container = dia.find(".euploadify-dialog-container").euploadify($.extend({}, opts, {
				fit : true,
				border : false,
				noheader : true,
				value : value
			}));
			dia.euploadify = euploadify = container;
			uploadify = container.euploadify("uploadify");
			euploadify.euploadify("resize");
		});
		function getValue() {
			if (!euploadify || !uploadify) {
				return value;
			}
			var eopts = euploadify.euploadify("options");
			return euploadify.euploadify(eopts.multi ? "getValues" : "getValue");
		}
		;
		return dia;
	};

	$.easyui.showEuploadifyDialog.defaults = {
		title : "文件上传对话框",
		iconCls : "icon-hamburg-publish",
		width : 750,
		height : "auto",
		minWidth : 400,
		minHeight : 160,
		maximizable : true,
		collapsible : true,
		multi : false,
		value : null,
		onEnter : function(val, editor, btn) {
		},
		onCancel : function(val, editor, btn) {
		}
	};

	$.fn.euploadify.methods = {

		options : function(jq) {
			return getOptions(jq[0]);
		},

		panel : function(jq) {
			return $.data(jq[0], "euploadify").panel;
		},

		uploadify : function(jq) {
			return getUploadify(jq[0]);
		},

		buttons : function(jq) {
			return getButtons(jq[0]);
		},

		queueDOM : function(jq) {
			return getQueueDOM(jq[0]);
		},

		grid : function(jq) {
			return getGrid(jq[0]);
		},

		// 从当前上传队列中取消一个或多个文件的上传；该方法的参数 param 可以定义为如下数据类型：
		// String : 表示要取消上传的文件的 id 值；如果不定义该参数，则取消队列中第一个文件的上传；如果该值定义为
		// "*"，则取消队列中所有文件上传；
		// Boolean : 默认为 false；如果定义为 true，则执行该方法时将不触发 onUploadCancel 事件；
		// 返回值：返回表示当前 easyui-euploadify 控件的 jQuery 链式对象。
		cancel : function(jq, param) {
			return jq.each(function() {
				cancel(this, param);
			});
		},
		setQueueData:function(jp,file){
			return jp.each(function(){
				setQueueData(this,file);
			})
		},

		// 从当前文档上下文中销毁该 easyui-euploadify 控件；该方法将触发 onDestroy 事件；
		// 返回值：返回表示当前 easyui-euploadify 控件的 jQuery 链式对象。
		destroy : function(jq) {
			return jq.each(function() {
				destroy(this);
			});
		},

		// 禁用该 easyui-euploadify 控件；该方法将触发 onDisable 事件；
		// 该方法的参数 setDisabled 为 Boolean 类型值，为 true 时表示禁用上传按钮；为 false 表示启用上传按钮；
		// 注意：该方法会导致当前的上传任务停止；
		// 返回值：返回表示当前 easyui-euploadify 控件的 jQuery 链式对象。
		disable : function(jq, setDisabled) {
			return jq.each(function() {
				disable(this, setDisabled);
			});
		},

		// 获取或设置 easyui-euploadify 控件中指定名称的属性值；该方法的参数 param 可以定义为如下数据类型：
		// String : 该参数指定一个属性名称，该属性名所示的属性值将会被返回；
		// Object : 格式如 { name: string, value: object }；设定指定名称的属性为指定的值。
		// 返回值：返回表示当前 easyui-euploadify 控件中指定名称的属性值；或者返回表示当前 easyui-euploadify
		// 控件的 jQuery 链式对象。
		settings : function(jq, param) {
			return settings(jq[0], param);
		},

		// 停止当前上传队列中所有文件的上传。
		// 返回值：返回表示当前 easyui-euploadify 控件的 jQuery 链式对象。
		stop : function(jq) {
			return jq.each(function() {
				stop(this);
			});
		},

		// 获取当前上传队列中有多少文件数量；
		// 返回值：返回一个 array 类型数组，数组中的每一项都是一个 file 对象；
		queues : function(jq) {
			return getQueues(jq[0]);
		},

		// 立即上传当前队列中的特定文件或所有文件。该方法的参数 param 可以定义为如下数据类型：
		// String : 表示要立即上传的文件 id 值；如果不定义该参数，则上传队列中的第一个文件；如果该值定义为
		// "*"，则上传队列中所有文件；
		// 返回值：返回表示当前 easyui-euploadify 控件的 jQuery 链式对象。
		upload : function(jq, param) {
			return jq.each(function() {
				upload(this, param);
			});
		},

		setFormData : function(jq, param) {
			return jq.each(function() {
				setFormData(this, param);
			});
		},

		resetFormData : function(jq) {
			return jq.each(function() {
				resetFormData(this);
			});
		},

		clearFormData : function(jq) {
			return jq.each(function() {
				clearFormData(this);
			});
		},

		resize : function(jq, param) {
			return jq.each(function() {
				resize(this, param);
			});
		},

		enable : function(jq) {
			return jq.each(function() {
				enable(this);
			});
		},

		validate : function(jq) {
			return jq.each(function() {
				validate(this);
			});
		},

		isValid : function(jq) {
			return validate(jq[0]);
		},

		enableValidation : function(jq) {
			return jq.each(function() {
				setValidation(this, false)
			});
		},

		disableValidation : function(jq) {
			return jq.each(function() {
				setValidation(this, true)
			});
		},

		clear : function(jq) {
			return jq.each(function() {
				clear(this);
			});
		},

		reset : function(jq) {
			return jq.each(function() {
				reset(this);
			});
		},

		getValues : function(jq) {
			return getValues(jq[0]);
		},

		setValues : function(jq, values) {
			return jq.each(function() {
				setValues(this, values);
			});
		},

		getValue : function(jq) {
			return getValue(jq[0]);
		},

		setValue : function(jq, value) {
			return jq.each(function() {
				setValue(this, value);
			});
		},

		show : function(jq) {
			return jq.each(function() {
				show(this);
			});
		},

		hide : function(jq) {
			return jq.each(function() {
				hide(this);
			});
		}
	};

	$.fn.euploadify.defaults = {

		// 表示 "上传" 按钮的宽度(像素值)；
		width : 120,

		// 表示 "上传" 按钮的高度(像素值)；
		height : 30,

		// 表示当选择了待上传文件后，是否自动执行 upload 方法以上传文件；
		auto : true,

		// 表示 uploadify.swf SWFObject Flash 对象的相对路径；该参数必须设置正确，否则上传控件将无效；
		swf : "uploadify.swf",

		// 表示服务器端接收上传数据的 url 相对路径；该参数必须设置正确，否则上传控件将无效；
		uploader : "uploadify.php",

		// 表示能够上传文件的最大数量；当文件数超出此限制时，将会触发 onUploadError 事件；
		uploadLimit : 999,

		// 表示文件上传时进行 ajax 提交的方法；可选的值为 "post" 或 "get"；
		method : "post",

		// 表示文件在上传过程中，每一个文件块的上传超时事件(秒)；
		successTimeout : 30,

		// 表示被添加到 "上传" 按钮的 html-css 样式类名
		buttonClass : "",

		// 表示当鼠标移动至 "上传" 按钮时，鼠标显示的样式，可能的值为 "hand" 或 "arrow"
		buttonCursor : "hand",

		// 表示 "上传" 按钮附加的背景图片；如果需要设置一个 "上传" 按钮的鼠标悬停时显示的图标，可以用 buttonClass
		// 属性并定义一个具有 hover 效果的 css；
		buttonImage : null,

		// 表示 "上传" 按钮显示的按钮文本；该值也可以定义为 html 标签包含的文本内容，例如 <b>SELECT FILES</b>；
		buttonText : "SELECT FILES",

		// 表示是否校验服务器目标文件夹中已经存在待上传的文件名；
		// 该值如果定义为布尔值 false，则表示不进行校验；
		// 如果定义为一个服务器 url 地址例如 "/uploadify/check-exists.php"，则表示进行服务器校验；该地址如果返回
		// 1 则表示服务器上存在指定的文件名；如果返回 0 则表示不存在。
		checkExisting : false,

		// 表示是否开启 SWFUpload 对象的调试模式
		debug : false,

		// 表示待上传文件对象提交至服务器时，采用的表单字段名；例如当该值定义为 "Filedata" 时，ASP.NET 服务器端可以用
		// HttpContext.Current.Request["Filedata"] 获取文件的二进制对象；
		fileObjName : "Filedata",

		// 表示文件上传大小上限；
		// 该值可以定义为一个 Number 值，表示文件最大字节数(KB为单位)；
		// 也可以定义为一个以 "KB"、"MB" 或 "GB" 结尾的 String 值；
		// 如果该属性值为 0，则表示不限制文件的上传大小；
		fileSizeLimit : 0,

		// 表示可选择的上传文件类型的描述；
		fileTypeDesc : "All Files",

		// 表示可选择的上传文件的扩展名列表，多个扩展名用半角分号隔开，例如 "*.jpg; *.png; *.gif"
		// 注意：手动输入的文件名将会绕过此验证规则，因此在服务端还需要进行文件类型的校验；
		fileTypeExts : "*.*",

		// 表示随待上传文件被提交至服务器端时，被一并发送至服务器的表单参数；可以在 onUploadStart 事件中动态设置这些参数；
		formData : {},

		// 表示上传文件队列的 HTML 页面显示模板；该值定义为 false 表示按照默认格式显示；该模版中可以使用如下四个变量标签：
		// instanceID:
		// fileID:
		// fileName:
		// fileSize:
		// 模板使用变量标签的格式如：${fileName}.
		itemTemplate : false,

		// 表示是否能够同时上传多个文件；
		multi : true,

		// 一个 array: <string> 格式数组，数组中的每一项都是一个表示 uploadify 事件名称的字符串；
		// 该属性表示哪些事件在 uploadify 的生命周期中将不会被触发执行；
		overrideEvents : [],

		// 表示浏览器是否缓存 SWFObject；如果该值设置为 false，则 SWF 文件的 url 中将会被添加一个随机值参数，以实现
		// SWFObject 不缓存效果；
		preventCaching : true,

		// 表示文件上传时的文件上传进度显示方式；
		// percentage: 表示上传时显示上传进度百分比
		// speed: 表示上传时显示上传速度
		progressData : "percentage",

		// 一个 HTML-DOM 元素的 ID 值，用于作为文件上传队列显示的容器；如果定义该值，则文件上传队列中每个上传的元素将会被附加到这个
		// DOM 对象中；
		// 如果该值定义为 false，则文件上传队列显示容器将会动态生成；
		queueID : false,

		// 表示能够同时执行上传操作的文件最大数量；这并不限制该控件可上传文件的最大数量；要限制可上传文件最大数量请用 uploadLimit 参数；
		// 如果添加到上传队列中的文件数量超过此限制，将会触发 onSelectError 事件；
		queueSizeLimit : 99,

		// 表示是否可以移除已经上传完成的文件；
		removeCompleted : true,

		// 表示文件上传完成后将会延迟多少秒后采用上传队列中被移除；
		removeTimeout : 3,

		// 表示文件在上传过程中如果出错是否自动重新上传；
		requeueErrors : false,

		// 当上传队列中的一个或多个文件被执行 cancel 方法而从队列中取消时，该事件将会被触发；
		// file : object 类型值；表示被取消上传的文件对象；
		onCancel : function(file) {
		},

		// 当 cancel 方法被执行并且参数值为 "*"，该事件将会被触发；
		// queueItemCount: number 类型值；表示取消上传的文件总数量
		onClearQueue : function() {
		},

		// 当 destroy 方法被调用时，该事件将会被触发；
		onDestroy : function() {
		},

		// 当浏览文件对话框被关闭时，该事件将会被触发；如果该事件会添加至 overrideEvents
		// 属性，则在将文件添加到上传队列中时如果出现错误，将不会弹出警告消息；
		// queueData: object 类型值，格式如 { filesSelected: number, filesQueued:
		// number, filesReplaced: number, filesCancelled: number, filesErrored:
		// number }
		onDialogClose : function(queueData) {
		},

		// 当打开浏览文件对话框后，该事件将会被触发；注意，该事件函数不会在浏览文件对话框打开时被立即执行，而是在窗口关闭时执行。
		onDialogOpen : function() {
		},

		// 当 disable 方法被调用时，该事件将会被触发；
		onDisable : function() {
		},

		// 当 disable 方法被调用并且 setDisabled 值为 false 以启用按钮时，该事件将会被触发；
		onEnable : function() {
		},

		// 在上传控件初始化过程中，如果当前浏览器的 Flash 插件版本不兼容，该事件将会被触发；
		onFallback : function() {
		},

		// 在 easyui-euploadify 控件第一次被初始化完成后，该事件将会被触发；
		// instance: 表示 uploadify 对象；
		onInit : function(instance) {
		},

		// 当上传队列中所有文件被处理完成后，该事件将会被触发；
		// queueData: object 类型值，格式如 { uploadsSuccessful: number,
		// uploadsErrored: number }
		onQueueComplete : function(queueData) {
		},

		// 当打开文件浏览器对话框并选择了要上传的文件之后，该事件将会被触发；
		// file: 表示被选择的待上传文件；
		onSelect : function(file) {
		},

		// 当打开文件浏览器对话框并在选择文件出错后，该事件将会被触发；针对每个选择文件出错后，该事件都会被触发一次；
		// file: 表示触发异常事件的文件对象；
		// errorCode:表示错误代码，可能的值为如下几种：
		// QUEUE_LIMIT_EXCEEDED: 选定的文件数量超过限制；
		// FILE_EXCEEDS_SIZE_LIMIT:选定的文件大小超过限制；
		// INVALID_FILETYPE: 选定的文件类型超过限制；
		// errorMsg:表示触发该事件时的错误消息；
		onSelectError : function(file, errorCode, errorMsg) {
		},

		// 当该控件的 Flash 插件对象加载完成后，该事件将会被触发；
		onSWFReady : function() {
		},

		// 当文件上传完成(不管成功还是失败)，该事件将会被触发；针对每个上传的文件，该事件都会触发一次；
		// file: 表示触发该事件的文件对象；
		onUploadComplete : function(file) {
		},

		// 当文件上传失败后，该事件将会被触发；针对每个上传失败的文件，该事件都会触发一次；
		// file: 表示触发该事件的文件对象；
		// errorCode: 表示错误编号
		// errorMsg: 表示错误消息
		// errorString:表示错误消息字符串，可能包含所有的错误细节的可读内容；
		onUploadError : function(file, errorCode, errorMsg, errorString) {
		},

		// 当文件上传进度每次更新时，该事件将会被触发；针对每个上传文件的每次进度更新，该事件都会触发一次；
		// file: 表示触发该事件的文件对象；
		// bytesUploaded: 表示该文件自开始上传时至当前时刻已上传的字节总数；
		// bytesTotal: 表示该文件的字节总数；
		// totalBytesUploaded: 表示目前为止所有文件的上传字节总数；
		// totalBytesTotal: 表示所有文件的字节总数
		onUploadProgress : function(file, bytesUploaded, bytesTotal, totalBytesUploaded, totalBytesTotal) {
		},

		// 当文件上传进度每次更新时，该事件将会被触发；
		// file: 表示将要被上传的文件对象；
		onUploadStart : function(file) {
		},

		// 当文件上传成功完成时，该事件将会被触发；针对每个上传成功的文件，该事件都会触发一次；
		// file: 表示上传完成的文件对象；
		// data: 文件上传完成后，由服务器端返回的数据；
		// response: 表示文件是否上传成功；boolean 类型值；如果为 true 则表示文件上传成功；
		// 如果该值为 false，则表示当提交上传后并超过 successTimeout
		// 属性设置的超时时间后，服务器任未有数据返回(文件上传失败)；
		onUploadSuccess : function(file, data, response) {
		}
	};

	$
			.extend(
					$.fn.euploadify.defaults,
					{

						successTimeout : 3600,
						removeCompleted : false,
						formData : {
							folder : "uploads"
						},
						buttonText : "选择文件...",
						multi : false,
						auto : true,

						uploadText : "上传",
						stopText : "停止上传",
						cancelText : "取消上传",
						removeText : "移除选择",

						emptyText : "未选择文件",
						finishText : "上传完成!",
						errorText : "上传失败",

						// 设置按钮提示文字；
						// 该属性可以为一个格式如 { button: string, upload: string, stop:
						// string, cancel: string, remove: string }
						// 的对象，表示每个按钮的提示文字内容；
						// 也可以是一个 boolean 类型值，表示是否启用按钮文字提示；
						tooltip : {
							button : "打开文件浏览器窗口并选择需要上传的文件",
							upload : "上传当前文件队列中所有未上传的文件",
							stop : "停止当前文件上传队列中所有文件的上传动作",
							cancel : "取消当前文件队列中所有未上传文件的上传任务",
							remove : "取消选定行的上传任务并删除该行"
						},
						message : {
							queueEmpty : "当前上传队列中没有待上传文件.",
							mustNotEmpty : "请至少选择一行数据.",
							fileUploadSuccessCanntCancel : "该文件已经上传完成，无法取消！",
							fileUploadSuccess : "该文件已经上传完成！",
							fileCannotRename : "该文件处于\"{0}\"状态，不能编辑\"自定义文件名\"，编辑状态已撤销.",
							fileNameCannotEmpty : "自定义文件名不能为空（已经恢复）",
							fileUploadSuccessCanntRemove : "该文件已经上传完成，无法取消(如想移除该行请选中该行后点击上方按钮\"移除选择\")！"
						},
						gridColumnNames : {
							name : "全文件名",
							customeName : "自定义文件名",
							type : "类型",
							size : "大小",
							progress : "上传进度",
							progressValue : "进度值",
							filestatus : "状态",
							operate : "操作"
						},
						gridRowButtonNames : {
							cancel : "取消",
							upload : "上传"
						},
						gridRowContextNames : {
							edit : "编辑文件名",
							cancel : "取消该文件",
							upload : "上传该文件"
						},

						FILE_STATUS : {
							"-1" : "等待上传",
							"-2" : "正在上传...",
							"-3" : "上传出错",
							"-4" : "上传完成",
							"-5" : "已取消"
						},

						buttonIcon : "icon-search",
						stopIcon : "icon-hamburg-stop",
						cancelIcon : "icon-standard-cancel",
						uploadIcon : "icon-hamburg-publish",

						response : {
							"id" : null,
							"status" : false,
							"message" : null,
							"value" : null,
							"url" : null
						},
						requestFilter : function(data, file) {
							return data;
						},
						responseFilter : function(data, file) {
							return $.util.tryExec(function() {
								return $.util.parseJSON(data);
							});
						},

						// 在设置控件允许可以同时上传多个文件时(multi: true)，多文件列表的显示方式；String
						// 类型值，可选的值限定如下范围：
						// uploadify:
						// simple:
						// list:
						// grid:
						multiTemplate : "grid",

						multiTemplateData : {
							uploadify : $.fn.euploadify.defaults.itemTemplate,
							simple : "<div id=\"${fileID}\" class=\"uploadify-queue-item\">\
            		<div class=\"cancel\">\
            			<a href=\"javascript:$(\'#${instanceID}\').uploadify(\'cancel\', \'${fileID}\')\">X</a>\
            		</div>\
            		<span class=\"fileName\">${fileName} (${fileSize})</span><span class=\"data\"></span>\
            	 </div>",
							bootstrap : ""
						},

						value : null,

						disabled : false,

						buttonPlain : true,

						width : "auto",

						height : "auto",

						buttonWidth : 90,

						buttonHeight : 24,

						showStop : false,

						showCancel : false,

						required : false,
						missingMessage : "附件(文件/档)不能为空,请上传.",
						// "left", "right", "top", "bottom"
						tipPosition : "right",
						deltaX : 0,
						tipOptions : $.fn.validatebox.defaults.tipOptions,
						separator : ",",
						novalidate : false,

						onChange : function(newValue, oldValue) {
						},

						onButtonStop : function(queues, btnDOM) {
						}
					});

	$.parser.plugins.push("euploadify");

	if ($.fn.form && $.isArray($.fn.form.otherList)) {
		$.fn.form.otherList.push("euploadify");
		// $.array.insert($.fn.form.otherList, 0, "euploadify");
	}

})(jQuery);